﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using MathematicallySafe.Base;
using MathematicallySafe.HeadCounter.Data.Common;
using MathematicallySafe.Armourer.Base;
using MathematicallySafe.HeadCounter.Data;
using MathematicallySafe.HeadCounter.Data.Models;
using MathematicallySafe.HeadCounter.Services;
using MathematicallySafe.HeadCounter.ViewModels;
using MathematicallySafe.HeadCounter.Views;
using StructureMap;

namespace MathematicallySafe.HeadCounter
{
    public partial class App : System.Windows.Application
    {
        private static IHeadCounterService HeadCounterService;

        private void OnStartup(object sender, StartupEventArgs e)
        {
            InitialiseContainers();
            ObjectFactory.GetInstance<IAppLog<App>>().Info("HeadCounter started " + DateTime.Now);

            DispatcherUnhandledException += AppDispatcherUnhandledException;
            AppDomain.CurrentDomain.UnhandledException += UnhandledException;

            InitialiseHeadCounterService();

            var view = new HeadCounterView()
                       {
                           ViewModel = new HeadCounterViewModel()
                       };

            view.ViewModel.Initialise();
            view.Show();
        }

        private void InitialiseHeadCounterService()
        {
            HeadCounterService = ObjectFactory.GetInstance<IHeadCounterService>();

            if (Data.HeadCounterService.FirstTimeRun)
            {
                // todo add dialog here to get guild name and any must have initial options
                var options = new Options()
                                  {
                                      GuildName = "<Guild>",
                                      Region = WowRegion.EU,
                                      Realm = "<Realm>",
                                      ShortPeriodLength = 6,
                                      LongPeriodLength = 12,
                                      DefaultPeriod = Period.Short,
                                      iLevelBase = 226,
                                      iLevelProgression = 245,
                                      iLevelTierDifference = 13,
                                      MinAttendancePercent = 50,
                                      MaxEffectiveAttendancePercent = 90,
                                      HighAttendancePercentage = 90.0,
                                      GoodAttendancePercentage = 65.0,
                                      FairAttendancePercentage = 50.0,
                                      ReportOptionalRaids = true
                                  };

                var userOptions = new UserOptions()
                                      {
                                          HeadCounterPath = @"C:\World of Warcraft\Interface\AddOns\Broker_HeadCounter"
                                      };

                options.AddDefaultLootOverrides();

                HeadCounterService.Create(options, userOptions);
            }

            HeadCounterService.Load();
        }

        private static void InitialiseContainers()
        {
            ObjectFactory.Initialize(x => x.AddRegistry<HeadCounterRegistry>());
        }

        private void Application_Exit(object sender, ExitEventArgs e)
        {
            if (HeadCounterService.IsDirty) HeadCounterService.Save();    
            AutoBackup();

            ObjectFactory.GetInstance<IAppLog<App>>().Info("HeadCounter exited normally " + DateTime.Now);
        }

        private void AutoBackup()
        {
            var backupService = ObjectFactory.GetInstance<IBackupService>();

            backupService.ArchiveLocation = Constants.XmlDirectory;
            backupService.DataLocation = Constants.XmlDirectory;
            backupService.DataWildcard = @"/*.xml";
            backupService.ArchiveName = Constants.MainArchiveName;

            backupService.Backup();
        }


        void UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                var ex = (Exception)e.ExceptionObject;

                var log = ObjectFactory.GetInstance<IAppLog<App>>();
                log.Fatal("Unhandled exception detected, closing application. Message: " + ex.Message, ex);

                MessageBox.Show("ZOMG! HeadCounter has stopped working.", "Unhandled Error - Closing HeadCounter", MessageBoxButton.OK, MessageBoxImage.Stop);
            }
            finally
            {
                Shutdown(1);
            }
        }

        static void AppDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            var log = ObjectFactory.GetInstance<IAppLog<App>>();
            log.Fatal("HeadCounter unhandled dispatcher exception. Message: " + e.Exception.Message, e.Exception);

            e.Handled = true;
        }
    }
}